/*-------------------------------------------------------------------------
 *
 * genbki.h
 *	  所有 POSTGRES 目录头文件所需的包含文件。
 *
 * genbki.h 定义了 CATALOG()、BKI_BOOTSTRAP 和相关宏，
 * 以便目录头文件可以被 C 编译器读取。
 * （这些相同的词被 genbki.pl 识别，以从这些头文件构建 BKI
 * 引导文件。）
 *
 *
 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/catalog/genbki.h
 *
 *-------------------------------------------------------------------------
 */
#ifndef GENBKI_H
#define GENBKI_H

/* 引入目录的结构定义 */
#define CATALOG(name,oid,oidmacro)	typedef struct CppConcat(FormData_,name)

/* 可能出现在 CATALOG 之后的选项（在同一行） */
#define BKI_BOOTSTRAP
#define BKI_SHARED_RELATION
#define BKI_ROWTYPE_OID(oid,oidmacro)
#define BKI_SCHEMA_MACRO

/* 可能出现在属性之后的选项（在同一行） */
#define BKI_FORCE_NULL
#define BKI_FORCE_NOT_NULL
/* 为目录字段指定默认值 */
#define BKI_DEFAULT(value)
/* 指定自动生成数组类型的默认值 */
#define BKI_ARRAY_DEFAULT(value)
/*
 * 表示该属性包含引用命名目录的 OIDs；
 * 可应用于 oid、regproc、oid[] 或 oidvector 类型的列。
 * genbki.pl 使用此信息来了解如何在初始数据中执行名称查找
 * （如果有），并且它还用于回归测试有效性检查。
 * _OPT 后缀表示值可以为零而不是有效的 OID 引用。
 */
#define BKI_LOOKUP(catalog)
#define BKI_LOOKUP_OPT(catalog)

/*
 * 这些行由 genbki.pl 处理以创建语句，
 * 启动解析器将其转换为 BootstrapToastTable 命令。
 * 每行指定需要 toast 表的系统目录，
 * 分配给 toast 表的 OID，以及分配给
 * toast 表索引的 OID。我们硬编码这些 OIDs 的原因是我们
 * 需要用于共享关系的稳定 OIDs，这包括共享关系的 toast 表。
 *
 * DECLARE_TOAST_WITH_MACRO 变体在需要 C 宏时用于
 * toast 表/索引 OIDs（通常仅适用于共享目录）。
 *
 * 宏定义只是为了防止 C 编译器出现错误。
 */
#define DECLARE_TOAST(name,toastoid,indexoid) extern int no_such_variable
#define DECLARE_TOAST_WITH_MACRO(name,toastoid,indexoid,toastoidmacro,indexoidmacro) extern int no_such_variable

/*
 * 这些行由 genbki.pl 处理以创建语句，
 * 启动解析器将其转换为 DefineIndex 调用。
 *
 * 关键字为 DECLARE_INDEX 或 DECLARE_UNIQUE_INDEX 或
 * DECLARE_UNIQUE_INDEX_PKEY。 ("PKEY" 将索引标记为目录的
 * 主键；目前这与常规唯一索引仅在表面上不同。根据惯例，
 * 如果目录的 OID 列存在，我们通常将其设置为主键。)
 *
 * 前两个参数是索引的名称和 OID。第三个参数
 * 是为其 OID 生成的 #define 的名称。
 * C 代码中对索引的引用应始终使用这些 #defines，而不是实际的索引名称
 * （更不用说数字 OID）。其余部分类似于标准的 'create
 * index' SQL 命令。
 *
 * 宏定义只是为了防止 C 编译器出现错误。
 */
#define DECLARE_INDEX(name,oid,oidmacro,decl) extern int no_such_variable
#define DECLARE_UNIQUE_INDEX(name,oid,oidmacro,decl) extern int no_such_variable
#define DECLARE_UNIQUE_INDEX_PKEY(name,oid,oidmacro,decl) extern int no_such_variable

/*
 * 这些行通知 genbki.pl 关于手动分配的 OIDs，这些 OIDs 不
 * 对应于 catalog *.dat 文件中的任何条目，但应以唯一性验证
 * 和 renumber_oids.pl 的重新编号为基础。 C 宏
 * 被发射到相应的 *_d.h 文件中，以 #define 给定的名称。
 */
#define DECLARE_OID_DEFINING_MACRO(name,oid) extern int no_such_variable

/*
 * 这些行由 genbki.pl 处理以创建一个表供
 * pg_get_catalog_foreign_keys() 函数使用。我们没有任何
 * 实际强制系统目录中外键关系的机制，但以机器可读的形式记录预期
 * 关系仍然很有用。
 *
 * 关键字为 DECLARE_FOREIGN_KEY[_OPT] 或 DECLARE_ARRAY_FOREIGN_KEY[_OPT]。
 * 第一个参数是引用列的括号列表；
 * 第二个是被引用表的名称；第三个是被引用列的括号
 * 列表。使用 ARRAY 宏意味着最后的引用列是一个数组，
 * 其每个元素都应与最后被引用列中的某个条目匹配。
 * 使用 OPT 后缀表示引用列可以为零，而不是有效的
 * 引用。
 *
 * 用 BKI_LOOKUP 规则标记的列不需要显式
 * DECLARE_FOREIGN_KEY 宏，因为 genbki.pl 可以从中推断 FK 关系。
 * 因此，这些宏仅在特殊情况下需要。
 *
 * 宏定义只是为了防止 C 编译器出现错误。
 */
#define DECLARE_FOREIGN_KEY(cols,reftbl,refcols) extern int no_such_variable
#define DECLARE_FOREIGN_KEY_OPT(cols,reftbl,refcols) extern int no_such_variable
#define DECLARE_ARRAY_FOREIGN_KEY(cols,reftbl,refcols) extern int no_such_variable
#define DECLARE_ARRAY_FOREIGN_KEY_OPT(cols,reftbl,refcols) extern int no_such_variable

/* 以下内容从未定义；它们仅用于文档。 */

/*
 * 变量长度目录字段（除了可能第一个不可为空的字段） 
 * 不应在 C 结构中可见，因此通过未定义符号的 #ifdef 隐藏它们。
 * 有关如何处理此问题，请参见 bootstrap.c 中的 BOOTCOL_NULL_AUTO 代码。
 */
#undef CATALOG_VARLEN

/*
 * 某些目录头文件中的代码需要对客户端可见，
 * 但我们不希望客户端包含完整的头文件，因为 
 * 头文件中其他代码的安全性问题。为此，
 * 用 "#ifdef EXPOSE_TO_CLIENT_CODE" 包围应对客户端可见的代码。
 * 这指示 genbki.pl 在生成相应的 "_d" 头文件时复制该部分，
 * 该头文件可以被客户端和后端代码都包含。
 */
#undef EXPOSE_TO_CLIENT_CODE

#endif							/* GENBKI_H */
